#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <png.h>
#include "png.h"

extern int *lcd_ptr;

// PNG错误处理结构体
typedef struct {
    png_structp png_ptr;
    png_infop info_ptr;
    png_infop end_info;
    png_bytep *row_pointers;
    png_bytep buffer;
    int width, height;
    png_byte color_type;
    png_byte bit_depth;
} PNG_Data;

// PNG错误处理函数
static void png_error_handler(png_structp png_ptr, png_const_charp error_msg) {
    fprintf(stderr, "PNG Error: %s\n", error_msg);
    longjmp(png_jmpbuf(png_ptr), 1);
}

// PNG警告处理函数
static void png_warning_handler(png_structp png_ptr, png_const_charp warning_msg) {
    fprintf(stderr, "PNG Warning: %s\n", warning_msg);
}

// 读取PNG文件
static PNG_Data* read_png_file(const char *filename) {
    FILE *fp = fopen(filename, "rb");
    if (!fp) {
        fprintf(stderr, "Cannot open PNG file: %s\n", filename);
        return NULL;
    }

    // 检查PNG签名
    unsigned char header[8];
    fread(header, 1, 8, fp);
    if (png_sig_cmp(header, 0, 8)) {
        fprintf(stderr, "Not a valid PNG file: %s\n", filename);
        fclose(fp);
        return NULL;
    }

    PNG_Data *png_data = malloc(sizeof(PNG_Data));
    if (!png_data) {
        fclose(fp);
        return NULL;
    }

    // 创建PNG读取结构
    png_data->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 
                                              png_data, png_error_handler, png_warning_handler);
    if (!png_data->png_ptr) {
        free(png_data);
        fclose(fp);
        return NULL;
    }

    // 创建信息结构
    png_data->info_ptr = png_create_info_struct(png_data->png_ptr);
    if (!png_data->info_ptr) {
        png_destroy_read_struct(&png_data->png_ptr, NULL, NULL);
        free(png_data);
        fclose(fp);
        return NULL;
    }

    // 创建结束信息结构
    png_data->end_info = png_create_info_struct(png_data->png_ptr);
    if (!png_data->end_info) {
        png_destroy_read_struct(&png_data->png_ptr, &png_data->info_ptr, NULL);
        free(png_data);
        fclose(fp);
        return NULL;
    }

    // 设置错误处理
    if (setjmp(png_jmpbuf(png_data->png_ptr))) {
        png_destroy_read_struct(&png_data->png_ptr, &png_data->info_ptr, &png_data->end_info);
        free(png_data);
        fclose(fp);
        return NULL;
    }

    // 初始化PNG I/O
    png_init_io(png_data->png_ptr, fp);
    png_set_sig_bytes(png_data->png_ptr, 8);

    // 读取PNG信息
    png_read_info(png_data->png_ptr, png_data->info_ptr);

    png_data->width = png_get_image_width(png_data->png_ptr, png_data->info_ptr);
    png_data->height = png_get_image_height(png_data->png_ptr, png_data->info_ptr);
    png_data->color_type = png_get_color_type(png_data->png_ptr, png_data->info_ptr);
    png_data->bit_depth = png_get_bit_depth(png_data->png_ptr, png_data->info_ptr);

    // 转换到8位RGB
    if (png_data->bit_depth == 16)
        png_set_strip_16(png_data->png_ptr);

    if (png_data->color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png_data->png_ptr);

    if (png_data->color_type == PNG_COLOR_TYPE_GRAY && png_data->bit_depth < 8)
        png_set_expand_gray_1_2_4_to_8(png_data->png_ptr);

    if (png_get_valid(png_data->png_ptr, png_data->info_ptr, PNG_INFO_tRNS))
        png_set_tRNS_to_alpha(png_data->png_ptr);

    if (png_data->color_type == PNG_COLOR_TYPE_GRAY ||
        png_data->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
        png_set_gray_to_rgb(png_data->png_ptr);

    // 更新信息
    png_read_update_info(png_data->png_ptr, png_data->info_ptr);

    // 分配内存
    int rowbytes = png_get_rowbytes(png_data->png_ptr, png_data->info_ptr);
    png_data->buffer = malloc(rowbytes * png_data->height);
    png_data->row_pointers = malloc(png_data->height * sizeof(png_bytep));

    if (!png_data->buffer || !png_data->row_pointers) {
        if (png_data->buffer) free(png_data->buffer);
        if (png_data->row_pointers) free(png_data->row_pointers);
        png_destroy_read_struct(&png_data->png_ptr, &png_data->info_ptr, &png_data->end_info);
        free(png_data);
        fclose(fp);
        return NULL;
    }

    // 设置行指针
    for (int i = 0; i < png_data->height; i++) {
        png_data->row_pointers[i] = png_data->buffer + i * rowbytes;
    }

    // 读取图像数据
    png_read_image(png_data->png_ptr, png_data->row_pointers);

    fclose(fp);
    return png_data;
}

// 释放PNG数据
static void free_png_data(PNG_Data *png_data) {
    if (png_data) {
        if (png_data->buffer) free(png_data->buffer);
        if (png_data->row_pointers) free(png_data->row_pointers);
        if (png_data->png_ptr) png_destroy_read_struct(&png_data->png_ptr, &png_data->info_ptr, &png_data->end_info);
        free(png_data);
    }
}

// 绘制PNG图片到LCD
int lcd_draw_png(const char *pathname, int x, int y) {
    PNG_Data *png_data = read_png_file(pathname);
    if (!png_data) {
        return -1;
    }

    int channels = png_get_channels(png_data->png_ptr, png_data->info_ptr);

    // 绘制到LCD
    for (int j = 0; j < png_data->height; j++) {
        for (int i = 0; i < png_data->width; i++) {
            int r, g, b, a = 255;
            
            if (channels == 4) {
                // RGBA
                r = png_data->row_pointers[j][i * 4 + 0];
                g = png_data->row_pointers[j][i * 4 + 1];
                b = png_data->row_pointers[j][i * 4 + 2];
                a = png_data->row_pointers[j][i * 4 + 3];
            } else if (channels == 3) {
                // RGB
                r = png_data->row_pointers[j][i * 3 + 0];
                g = png_data->row_pointers[j][i * 3 + 1];
                b = png_data->row_pointers[j][i * 3 + 2];
            } else {
                // 灰度
                r = g = b = png_data->row_pointers[j][i];
            }

            // 处理透明度
            if (a > 0) {
                int color = b | (g << 8) | (r << 16);
                lcd_ptr[800 * (j + y) + i + x] = color;
            }
        }
    }

    free_png_data(png_data);
    return 0;
}

// 缩放绘制PNG图片到LCD
int lcd_draw_scale_png(const char *pathname, int x, int y, int w, int h) {
    PNG_Data *png_data = read_png_file(pathname);
    if (!png_data) {
        return -1;
    }

    int channels = png_get_channels(png_data->png_ptr, png_data->info_ptr);

    // 计算缩放比例
    float scale_x = (float)png_data->width / w;
    float scale_y = (float)png_data->height / h;

    // 绘制到LCD
    for (int j = 0; j < h; j++) {
        for (int i = 0; i < w; i++) {
            int src_x = (int)(i * scale_x);
            int src_y = (int)(j * scale_y);
            
            if (src_x >= png_data->width) src_x = png_data->width - 1;
            if (src_y >= png_data->height) src_y = png_data->height - 1;

            int r, g, b, a = 255;
            
            if (channels == 4) {
                // RGBA
                r = png_data->row_pointers[src_y][src_x * 4 + 0];
                g = png_data->row_pointers[src_y][src_x * 4 + 1];
                b = png_data->row_pointers[src_y][src_x * 4 + 2];
                a = png_data->row_pointers[src_y][src_x * 4 + 3];
            } else if (channels == 3) {
                // RGB
                r = png_data->row_pointers[src_y][src_x * 3 + 0];
                g = png_data->row_pointers[src_y][src_x * 3 + 1];
                b = png_data->row_pointers[src_y][src_x * 3 + 2];
            } else {
                // 灰度
                r = g = b = png_data->row_pointers[src_y][src_x];
            }

            // 处理透明度
            if (a > 0) {
                int color = b | (g << 8) | (r << 16);
                lcd_ptr[800 * (j + y) + i + x] = color;
            }
        }
    }

    free_png_data(png_data);
    return 0;
} 